import { Building } from '../Building';
import { City } from '../../City';
import { DEG2RAD } from 'three/src/math/MathUtils.js';
import { assetManager } from '../../../AssetManager.js';

const TOP = 0b0001;
const BOTTOM = 0b0010;
const LEFT = 0b0100;
const RIGHT = 0b1000;
const TOP_BOTTOM_LEFT_RIGHT = TOP | BOTTOM | LEFT | RIGHT;
const BOTTOM_LEFT_RIGHT = BOTTOM | LEFT | RIGHT;
const TOP_LEFT_RIGHT = TOP | LEFT | RIGHT;
const TOP_BOTTOM_RIGHT = TOP | BOTTOM | RIGHT;
const TOP_BOTTOM_LEFT = TOP | BOTTOM | LEFT;
const LEFT_RIGHT = LEFT | RIGHT;
const TOP_RIGHT = TOP | RIGHT;
const TOP_BOTTOM = TOP | BOTTOM;
const BOTTOM_RIGHT = BOTTOM | RIGHT;
const TOP_LEFT = TOP | LEFT;
const BOTTOM_LEFT = BOTTOM | LEFT;

/** 道路 */
export class Road extends Building {

    style: string;

    constructor() {

        super();

        this.type = 'road';
        this.name = 'Road';
        this.style = 'straight';
        this.hideTerrain = true;
        this.roadAccess.enabled = false;

    }

    refreshView(city: City) {

        // 检查道路网格4个方向的所有连通关系，更新样式
        this.updateRoadStyle(city);

        const mesh = assetManager.getModel(`road-${this.style}`, this);
        this.setMesh(mesh);
        // city.vehicleGraph.updateTile(this.x, this.y, this);
    }

    private updateRoadStyle(city: City): void {

        const roadType = this.type;
        // 检查哪些相邻的瓦片是道路
        const top = (city.getTile(this.x, this.y - 1)?.building?.type === roadType) ? TOP : 0;
        const bottom = (city.getTile(this.x, this.y + 1)?.building?.type === roadType) ? BOTTOM : 0;
        const left = (city.getTile(this.x - 1, this.y)?.building?.type === roadType) ? LEFT : 0;
        const right = (city.getTile(this.x + 1, this.y)?.building?.type === roadType) ? RIGHT : 0;

        const value = top | bottom | right | left;

        switch (value) {
            case TOP_BOTTOM_LEFT_RIGHT:
                this.style = 'four-way';
                this.rotation.y = 0;
                return;
            case BOTTOM_LEFT_RIGHT:
                this.style = 'three-way';
                this.rotation.y = 0;
                return;
            case TOP_LEFT_RIGHT:
                this.style = 'three-way';
                this.rotation.y = 180 * DEG2RAD;
                return;
            case TOP_BOTTOM_RIGHT:
                this.style = 'three-way';
                this.rotation.y = 90 * DEG2RAD;
                return;
            case TOP_BOTTOM_LEFT:
                this.style = 'three-way';
                this.rotation.y = 270 * DEG2RAD;
                return;
            case TOP_LEFT:
                this.style = 'corner';
                this.rotation.y = 180 * DEG2RAD;
                return;
            case TOP_RIGHT:
                this.style = 'corner';
                this.rotation.y = 90 * DEG2RAD;
                return;
            case BOTTOM_LEFT:
                this.style = 'corner';
                this.rotation.y = 270 * DEG2RAD;
                return;
            case BOTTOM_RIGHT:
                this.style = 'corner';
                this.rotation.y = 0;
                return;
            case TOP_BOTTOM:
                this.style = 'straight';
                this.rotation.y = 0;
                return;
            case LEFT_RIGHT:
                this.style = 'straight';
                this.rotation.y = 90 * DEG2RAD;
                return;
            case TOP:
                this.style = 'end';
                this.rotation.y = 180 * DEG2RAD;
                return;
            case BOTTOM:
                this.style = 'end';
                this.rotation.y = 0;
                return;
            case LEFT:
                this.style = 'end';
                this.rotation.y = 270 * DEG2RAD;
                return;
            case RIGHT:
                this.style = 'end';
                this.rotation.y = 90 * DEG2RAD;
                return;
            default:
                this.style = 'straight';
                this.rotation.y = 0;
        }

    }

    toHTML() {
        let html = super.toHTML();
        html += `
        <span class="info-label">Style </span>
        <span class="info-value">${this.style}</span>
        <br>
        `;
        return html;
    }
}